package handler

import (
	"context"
	"gozeroStandalone/define"
	"gozeroStandalone/internal/logic"
	"gozeroStandalone/internal/tools"
	"gozeroStandalone/utils"
	"math"
	"net/http"
	"strconv"
	"time"

	"github.com/google/uuid"
)

/*
 +----------------------------------------------------------------------
 + Title        : UserHandler
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2019-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 用户处理器
 +----------------------------------------------------------------------
*/
type UserHandler struct {
	BaseHandler
}

/**
 * 注册
 *
 * @param string username -------------------------必传
 * @param string mobile ---------------------------必传
 * @param string password -------------------------必传
 * @author huwl
 */
func (control *UserHandler) Register(w http.ResponseWriter, r *http.Request) {
	username := r.PostFormValue("username")
	mobile := r.PostFormValue("mobile")
	password := r.PostFormValue("password")

	if username == "" {
		control.BaseError(r, w, control.WithMessage("请输入用户名"))
		return
	}
	if !utils.CheckMobile(mobile) {
		control.BaseError(r, w, control.WithMessage("请输入正确格式的手机号"))
		return
	}
	if password == "" {
		control.BaseError(r, w, control.WithMessage("请输入密码"))
		return
	}

	userLogic := logic.NewUserLogicInstance(context.Background(), control.SvcCtx)
	err := userLogic.Register(map[string]interface{}{
		"username": username,
		"mobile":   mobile,
		"password": password,
	})
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(r, w, control.WithMessage("注册成功"))
}

/**
 * 登录
 *
 * @param string username -------------------------必传
 * @param string password -------------------------必传
 * @author huwl
 */
func (control *UserHandler) Login(w http.ResponseWriter, r *http.Request) {
	username := r.PostFormValue("username")
	password := r.PostFormValue("password")

	if username == "" {
		control.BaseError(r, w, control.WithMessage("请输入用户名"))
		return
	}
	if password == "" {
		control.BaseError(r, w, control.WithMessage("请输入密码"))
		return
	}

	// 调用逻辑层
	userLogic := logic.NewUserLogicInstance(context.Background(), control.SvcCtx)
	user, err := userLogic.Login(map[string]interface{}{"username": username, "password": password})
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	// 生成token
	token, err := utils.GenerateToken(uint64(user.Uid))
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	// 生成refreshToken
	refreshToken := uuid.New().String()

	// 需要将refreshToken存入redis
	ri, err := tools.NewRedisInstance(control.SvcCtx.Config)
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}
	err = ri.RedisSet("userRefreshToken:"+strconv.FormatInt(user.Uid, 10), refreshToken, time.Hour*12*10)
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(r, w, control.WithData(map[string]interface{}{
		"user":          user,
		"token":         token,
		"token_expire":  time.Now().Add(time.Duration(define.TokenExpireTime)).Unix(),
		"refresh_token": refreshToken,
	}), control.WithMessage("登录成功"))
}

/**
 * 列表
 *
 * @author huwl
 */
func (control *UserHandler) List(w http.ResponseWriter, r *http.Request) {
	uid := r.URL.Query().Get("uid")
	name := r.URL.Query().Get("name")
	nick := r.URL.Query().Get("nick")
	email := r.URL.Query().Get("email")
	username := r.URL.Query().Get("username")
	startCreateTime := r.URL.Query().Get("start_create_time")
	endCreateTime := r.URL.Query().Get("end_create_time")
	status := r.URL.Query().Get("status")
	page, _ := strconv.Atoi(r.URL.Query().Get("page"))
	pageSize, _ := strconv.Atoi(r.URL.Query().Get("page_size"))
	sortField := r.URL.Query().Get("sort_field")
	sortMode := r.URL.Query().Get("sort_mode")

	params := map[string]interface{}{
		"status <> ?": -2,
	}

	if uid != "" {
		params["uid"] = uid
	}
	if name != "" {
		params["name"] = name
	}
	if nick != "" {
		params["nick"] = nick
	}
	if email != "" {
		params["email"] = email
	}
	if username != "" {
		params["username"] = username
	}
	if status != "all" {
		params["status IN (?)"] = utils.IntSplit(status, ",")
	}
	if startCreateTime != "" {
		params["create_time >= ?"] = startCreateTime + " 00:00:00"
	}
	if endCreateTime != "" {
		params["create_time <= ?"] = endCreateTime + " 23:59:59"
	}
	if page == 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 10
	}
	if sortField == "" {
		sortField = "uid"
	}
	if sortMode == "" {
		sortMode = "DESC"
	}

	userLogic := logic.NewUserLogicInstance(context.Background(), control.SvcCtx)
	users, total, err := userLogic.List(params, uint32(page), int8(pageSize), sortField+" "+sortMode)
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(r, w, control.WithData(map[string]interface{}{
		"page":       page,
		"page_size":  pageSize,
		"total":      total,
		"page_total": math.Ceil(float64(total) / float64(pageSize)),
		"users":      users,
	}))
}

/**
 * 数量
 *
 * @author huwl
 */
func (control *UserHandler) Total(w http.ResponseWriter, r *http.Request) {
	uid := r.URL.Query().Get("uid")
	name := r.URL.Query().Get("name")
	nick := r.URL.Query().Get("nick")
	email := r.URL.Query().Get("email")
	username := r.URL.Query().Get("username")
	startCreateTime := r.URL.Query().Get("start_create_time")
	endCreateTime := r.URL.Query().Get("end_create_time")
	status := r.URL.Query().Get("status")

	params := map[string]interface{}{
		"status <> ?": -2,
	}

	if uid != "" {
		params["uid"] = uid
	}
	if name != "" {
		params["name"] = name
	}
	if nick != "" {
		params["nick"] = nick
	}
	if email != "" {
		params["email"] = email
	}
	if username != "" {
		params["username"] = username
	}
	if status != "all" {
		params["status IN (?)"] = utils.IntSplit(status, ",")
	}
	if startCreateTime != "" {
		params["create_time >= ?"] = startCreateTime + " 00:00:00"
	}
	if endCreateTime != "" {
		params["create_time <= ?"] = endCreateTime + " 23:59:59"
	}

	userLogic := logic.NewUserLogicInstance(context.Background(), control.SvcCtx)
	total, err := userLogic.Total(params)
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(r, w, control.WithData(map[string]interface{}{
		"total": total,
	}))
}

/**
 * 批量新增
 *
 * @author huwl
 */
func (control *UserHandler) BatchAdd(w http.ResponseWriter, r *http.Request) {
	userLogic := logic.NewUserLogicInstance(context.Background(), control.SvcCtx)
	i, err := userLogic.BatchAdd([]map[string]interface{}{
		map[string]interface{}{
			"username": "萨芬",
			"mobile":   "18911112232",
		},
		map[string]interface{}{
			"username": "挂号费",
			"mobile":   "18911112254",
		},
		map[string]interface{}{
			"username": "二刚发的",
			"mobile":   "18911112213",
		},
	})
	if err != nil {
		control.BaseError(r, w, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(r, w, control.WithData(map[string]interface{}{
		"i": i,
	}))
}
